<!-- 词汇分类分析 -->
<template>
  <div class="w-full statistical-center">
    <statisticalHeader />
    <div class="px-40px pb-60px m--9px flex flex-1 gap-10px flex-col">
      <div class="flex items-center justify-between">
        <div class="flex items-center gap-12px text-14px">
          <div class="flex items-center gap-6px">
            <span class="text-#333">截止日期</span>
            <el-date-picker
              class="!w-160px"
              popper-class="popper-date-class"
              v-model="queryDate"
              type="date"
              placeholder="请选择日期"
              value-format="YYYYMMDD"
              :clearable="false"
            />
          </div>
          <ClassStudentCascader @change="cascaderChange" />
        </div>
        <div>
          <aiGenerateReport :sendContent="sendContent" :roleId="51" />
        </div>
      </div>
      <el-scrollbar
        ref="echartWarpRef"
        class="statistical-center-content"
        view-class="pb-60px flex gap-20px flex-wrap"
        v-loading="loading"
      >
        <div class="echart-card w-909px">
          <Echart
            :width="getViewportPx(900)"
            :height="getViewportPx(420)"
            :options="posDistributionOption"
          />
        </div>
        <div class="echart-card w-909px">
          <Echart
            :width="getViewportPx(900)"
            :height="getViewportPx(420)"
            :options="contentVsFunctionOption"
          />
        </div>
        <div class="echart-card w-909px">
          <Echart
            :width="getViewportPx(900)"
            :height="getViewportPx(420)"
            :options="wordFreqOption"
          />
        </div>
        <div class="echart-card w-909px">
          <Echart
            :width="getViewportPx(900)"
            :height="getViewportPx(420)"
            :options="ageMasteryRatioOption"
          />
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>
<script setup lang="ts">
import { getDictLabel, DICT_TYPE } from '@/utils/dict'
import { getViewportPx } from '@/utils/formatter'
import { statisticalCenterApi } from '@/api/school/statisticalCenter/index'
import { useBarOptions } from '@/hooks/chart/useBarOptions'
import { usePieOptions } from '@/hooks/chart/usePieOptions'
import { useScatterOptions } from '@/hooks/chart/useScatterOptions'
import { useLiquidFillOptions } from '@/hooks/chart/useLiquidFillOptions'
import statisticalHeader from './components/statisticalHeader.vue'
import aiGenerateReport from './components/aiGenerateReport.vue'
import { getAxisNameConfig, getDataZoomConfig } from './utils'
import { formatDate } from '@/utils/formatTime'
import { isNumber } from '@/utils/is'
const pageData: any = ref({})
const wordsFreqData: any = ref({})
const loading = ref(true)
const cascaderParams: any = ref({})
const pathLabels = ref([])
const nowDateStr = formatDate(new Date(), 'YYYYMMDD')
const queryDate = ref(nowDateStr)
const queryParams = computed(() => {
  return {
    startTime: queryDate.value,
    endTime: queryDate.value,
    ...cascaderParams.value
  }
})

// 发送内容
const sendContent = computed(() => {
  const baseData = {
    startTime: queryParams.value.startTime,
    endTime: queryParams.value.endTime,
    type: pathLabels.value.length - 1,
    target: pathLabels.value.join('-'),
    data: `${JSON.stringify(pageData.value)}${JSON.stringify(wordsFreqData.value)}`
  }
  return baseData
})

// 请求接口
const requestApiMap = computed(() => {
  let baseApi = statisticalCenterApi.getSchoolVocabularyReport
  if (queryParams.value.studentId) {
    baseApi = statisticalCenterApi.getSpeechReport
  } else if (queryParams.value.classId) {
    baseApi = statisticalCenterApi.getClassVocabularyReport
  }
  return {
    baseApi
  }
})

const init = async () => {
  if (!Object.keys(cascaderParams.value).length) {
    return
  }
  try {
    loading.value = true
    pageData.value = await requestApiMap.value.baseApi(queryParams.value)
    wordsFreqData.value = {}
    if (queryParams.value.studentId) {
      wordsFreqData.value = await statisticalCenterApi.getWordsFreqReport(queryParams.value)
    }
  } catch (error) {
    console.log(error)
  } finally {
    loading.value = false
  }
}
const cascaderChange = async (params, cascaderPathLabels) => {
  cascaderParams.value = params
  pathLabels.value = cascaderPathLabels
}
const calculateProccessedData = (rawData, maxHeight, maxNum) => {
  const curMaxHeight = parseInt(getViewportPx(maxHeight, true))
  const minBarHeight = (20 / curMaxHeight) * maxNum
  return rawData.map(function (val) {
    return {
      value: Math.max(val, minBarHeight),
      rawValue: val
    }
  })
}
const posDistributionOption = computed(() => {
  // 园区、班级图表配置
  let dataMap1: any = []
  let dataMap2: any = []
  let nameMap: any = pageData.value?.map?.((item: any) => item.className || item.studentName) || []

  let tooltip: any = {
    formatter: function (params) {
      return `${params[0].name}<br />${params
        ?.reverse()
        ?.map?.((item) => `${item.marker}${item.seriesName}: ${item.data?.rawValue}`)
        .join('<br />')}`
    }
  }

  const itemNumMap: any =
    pageData.value?.map?.((item: any) =>
      item?.posAvgCount || item?.posCount
        ? Object.values(item?.posAvgCount || item.posCount)?.reduce(
            (acc: number, curr: number) => acc + curr,
            0
          )
        : 0
    ) || []
  const max = Math.max.apply(null, itemNumMap)
  const posKeyMap =
    pageData.value?.[0]?.posAvgCount || pageData.value?.[0]?.posCount
      ? Object.keys(pageData.value?.[0]?.posAvgCount || pageData.value?.[0]?.posCount)
      : []

  let series = posKeyMap?.map?.((key) => {
    const rawData = pageData.value?.map?.(
      (item: any) => (item?.posAvgCount || item?.posCount)[key] || 0
    )
    const data = calculateProccessedData(rawData, 310, max)

    return {
      name: getDictLabel(DICT_TYPE.POS_CATEGORY_TO_CHINESE, key),
      stack: 'total',
      barWidth: getViewportPx(60),
      barMinHeight: 0,
      label: {
        show: true,
        position: 'inside',
        color: '#fff',
        formatter: function (params) {
          return params.data.rawValue
        }
      },
      itemStyle: {
        borderRadius: 0
      },
      data
    }
  })
  if (cascaderParams.value.studentId) {
    // 学生图表配置
    nameMap = pageData.value?.posDistribution
      ? Object.keys(pageData.value?.posDistribution)?.map?.((key) =>
          getDictLabel(DICT_TYPE.POS_CATEGORY_TO_CHINESE, key)
        )
      : []
    const baseDataMap = pageData.value?.posDistribution
      ? Object.values(pageData.value?.posDistribution)
      : []
    dataMap1 = baseDataMap?.map?.((item: any) => item.count) || []
    dataMap2 = baseDataMap?.map?.((item: any) => Math.floor(item.ratio * 100 * 100) / 100) || []
    tooltip = {}
  }

  return useBarOptions([], {
    title: {
      text: '词汇类型数量统计',
      left: 'center'
    },
    grid: {
      top:
        !cascaderParams.value?.studentId && pageData.value.length > 6
          ? getViewportPx(100, true)
          : '60',
      right: getViewportPx(15),
      left: getViewportPx(80)
    },
    dataZoom: !cascaderParams.value?.studentId &&
      pageData.value.length > 6 && [getDataZoomConfig()],
    legend: {
      right: getViewportPx(15)
    },
    tooltip: {
      ...tooltip
    },
    yAxis: {
      ...getAxisNameConfig('单位：个'),
      ...(!cascaderParams?.value?.studentId && {
        max: max + 200
      })
    },
    xAxis: {
      data: nameMap
    },
    series: series.length
      ? series
      : [
          {
            name: '词汇量',
            barWidth: getViewportPx(20),
            itemStyle: {
              color: '#8945FF'
            },
            data: dataMap1
          },
          dataMap2?.length && {
            name: '占比比例',
            type: 'line',
            symbol: 'circle',
            itemStyle: {
              color: '#47D147'
            },
            data: dataMap2
          }
        ]
  }).baseOptions
})
const contentVsFunctionMap = {
  contentWordCount: '实词',
  functionWordCount: '虚词'
}
const contentVsFunctionOption = computed(() => {
  if (!cascaderParams.value.studentId) {
    // 园区、班级图表配置
    return useBarOptions([], {
      title: {
        text: '实词与虚词统计',
        left: 'center'
      },
      grid: {
        top:
          !cascaderParams.value?.studentId && pageData.value.length > 6
            ? getViewportPx(100, true)
            : '60',
        right: getViewportPx(15),
        left: getViewportPx(80)
      },
      dataZoom: !cascaderParams.value?.studentId &&
        pageData.value.length > 6 && [getDataZoomConfig()],
      xAxis: {
        data: pageData.value?.map?.((item: any) => item.className || item.studentName) || []
      },
      yAxis: {
        ...getAxisNameConfig('单位：个')
      },
      series: [
        {
          name: '实词',
          barWidth: getViewportPx(20),
          barGap: '50%',
          data: pageData.value?.map?.((item) => item.contentWordAvg || item.contentWordCount || 0)
        },
        {
          name: '虚词',
          data: pageData.value?.map?.((item) => item.functionWordAvg || item.contentWordCount || 0)
        }
      ]
    }).baseOptions
  }
  const dataMap = pageData.value?.contentVsFunction
    ? Object.entries(pageData.value?.contentVsFunction).map(([key, value]) => {
        if (contentVsFunctionMap[key]) {
          return {
            name: contentVsFunctionMap[key],
            value
          }
        }
      })
    : []
  return usePieOptions(dataMap, {
    title: {
      text: '实词与虚词统计',
      left: 'center'
    }
    // legend: {
    //   orient: 'vertical',
    //   right: getViewportPx(20),
    //   bottom: '50%'
    // }
  }).baseOptions
})
const wordFreqOption = computed(() => {
  if (!cascaderParams.value.studentId) {
    // 园区、班级图表配置
    return useBarOptions(
      pageData.value?.map?.((item: any) => ({
        value: item.masteryRatioAvg || item.masteryRatio || 0,
        name: item.className || item.studentName,
        label: {
          formatter: function (params) {
            return `${Math.floor(params.value * 10000) / 100}%`
          }
        }
      })) || [],
      {
        title: {
          text: '实词与虚词词汇率',
          left: 'center'
        },
        grid: {
          top:
            !cascaderParams.value?.studentId && pageData.value.length > 6
              ? getViewportPx(100, true)
              : '60',
          right: getViewportPx(15),
          left: getViewportPx(80)
        },
        dataZoom: !cascaderParams.value?.studentId &&
          pageData.value.length > 6 && [getDataZoomConfig()],
        tooltip: {
          formatter: function (params) {
            const paramsItem = params[0]
            return `${paramsItem.name}<br />${paramsItem.marker}比例: ${Math.floor(paramsItem.value * 10000) / 100}%`
          }
        },
        yAxis: {
          ...getAxisNameConfig('单位：比例'),
          axisLabel: {
            formatter(value) {
              return `${Math.floor(value * 10000) / 100}%`
            }
          }
        }
      }
    ).baseOptions
  }
  const markPoint = {
    label: {
      formatter(params) {
        return params.data.coord[0]
      }
    }
  }
  return useScatterOptions([], {
    title: {
      text: '实词与虚词词频统计',
      left: 'center'
    },
    tooltip: {
      formatter(params) {
        if (params.value.length > 1) {
          return `${params.marker}${params.seriesName}：${params.value[2]}<br/>${params.value[0]}次 | ${Math.floor(params.value[1] * 10000) / 100}%`
        } else {
          return `${params.marker}${params.seriesName}<br/>${params.name}${params.data.coord[0]}次`
        }
      }
    },
    xAxis: {
      axisLabel: {
        formatter: '{value} 次'
      }
    },
    yAxis: {
      ...getAxisNameConfig('单位：比例'),
      axisLabel: {
        formatter(value) {
          return `${Math.floor(value * 10000) / 100}%`
        }
      }
    },
    series: [
      {
        name: '虚词',
        itemStyle: {
          color: '#78D0FF'
        },
        markPoint,
        data:
          wordsFreqData.value?.functionWords?.map((item: any) => [
            item.count,
            item.ratio,
            item.word
          ]) || []
      },
      {
        name: '实词',
        itemStyle: {
          color: '#47D147'
        },
        markPoint,
        data:
          wordsFreqData.value?.contentWords?.map((item: any) => [
            item.count,
            item.ratio,
            item.word
          ]) || []
      }
    ]
  }).baseOptions
})
const ageMasteryRatioOption = computed(() => {
  const masteryRatio = pageData.value?.vocabularyMastery?.masteryRatio
  return (
    isNumber(masteryRatio) &&
    useLiquidFillOptions([pageData.value?.vocabularyMastery?.masteryRatio], {
      title: {
        text: '已统计词汇与年龄标准占比',
        left: 'center'
      }
    }).baseOptions
  )
})
watch(
  () => queryParams.value,
  () => {
    init()
  },
  {
    immediate: true
  }
)
</script>
<style lang="scss" scoped>
@import url('./index.scss');

.echart-card {
  padding: 15px 0;
}
</style>
